﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;

namespace BranchTool
{
    public partial class frmMain : Form
    {
        private List<FileList> _fileList = new List<FileList>();
        private string _branchPath = "";

        public frmMain()
        {
            InitializeComponent();
        }

        private void btnFind_Click(object sender, EventArgs e)
        {
            SaveSetting();
            this.txtMessage.Text = "";
            this.txtFileList.Text = this.txtFileList.Text.Replace("/", "\\");
            AssortFile(this.txtFileList.Text.Trim());
            string strBranchPath = this.txtBranchPath.Text.Trim();

            #region Create BranchPath with date-time
            if (!Directory.Exists(strBranchPath))
            {
                Directory.CreateDirectory(strBranchPath);
            }
            if (strBranchPath.EndsWith("\\"))
            {
                strBranchPath += DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss");
            }
            else
            {
                strBranchPath = strBranchPath + "\\" + DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss");
            }
            if (!Directory.Exists(strBranchPath))
            {
                Directory.CreateDirectory(strBranchPath);
            }
            _branchPath = strBranchPath;
            #endregion

            #region Create Branch File
            foreach (FileList file in this._fileList)
            {
 
                string strFileFullPath = FindFile(file.FileName);
                string strDllFullPath = FindDll(file.FileName);
                
                if (file.FileProjectType == ProjectType.EventMail)
                {
                    if (strFileFullPath == "")
                    {
                        strFileFullPath =FindFile(file.FileName,this.txtCodePath.Text.Trim(),"");
                        string strPublish = this.txtPublishPath.Text.Trim();
                        if (strPublish.StartsWith("\\"))
                        {
                            strPublish = strPublish.Substring(1);
                        }
                        if (strFileFullPath.IndexOf("App_Code") > -1)
                        {
                            
                            strDllFullPath = FindFile("App_Code.dll", strPublish + "\\EventMail", "");
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strDllFullPath);
                        }
                        if (file.FileName.ToLower() == "Global.asax".ToLower())
                        {
                            strDllFullPath = FindFile("App_global.asax.dll", strPublish + "\\EventMail", "");
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strDllFullPath);
                        }
                    }
                    else
                    {
                        if (file.IsDLL)
                        {
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strDllFullPath);
                        }
                        else
                        {
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strFileFullPath);
                        }
                        
                    }
                   
                }
                else if(file.FileProjectType == ProjectType.SystemAdmin)
                {
                    if (strFileFullPath == "")
                    {
                        strFileFullPath = FindFile(file.FileName, this.txtCodePath.Text.Trim(), "");
                        string strPublish = this.txtPublishPath.Text.Trim();
                        if (strPublish.StartsWith("\\"))
                        {
                            strPublish = strPublish.Substring(1);
                        }
                        if (strFileFullPath.IndexOf("App_Code") > -1)
                        {

                            strDllFullPath = FindFile("App_Code.dll", strPublish + "\\SystemAdmin", "");
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strDllFullPath);
                        }
                        if (file.FileName.ToLower() == "Global.asax".ToLower())
                        {
                            strDllFullPath = FindFile("App_global.asax.dll", strPublish + "\\SystemAdmin", "");
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strDllFullPath);
                        }
                    }
                    else
                    {
                        if (file.IsDLL)
                        {
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strDllFullPath);
                        }
                        else
                        {
                            Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strFileFullPath);
                        }
                        
                        
                    }
                }
                else
                {
                    string strProjectDll = "";
                    if (strFileFullPath.EndsWith(".dll"))
                    {
                        strProjectDll = strFileFullPath;
                    }
                    else
                    {
                        strProjectDll = FindFile(GetProjectDllName(file.FileProjectType));
                    }
                    
                    Publish2Branch(this.txtPublishPath.Text.Trim(), strBranchPath, strProjectDll);
                }
            }

            #endregion

        }

        /// <summary>
        /// Save the lastest selected folders & filelist as default values.
        /// </summary>
        private void SaveSetting()
        {

            SettingHelp.Instance.SetSetting(this.txtPublishPath.Text.Trim(),this.txtCodePath.Text.Trim(),this.txtBranchPath.Text.Trim(),this.txtFileList.Text.Trim());
        }

        private void RecordMessage(string strMessage)
        {
            this.txtMessage.Text += strMessage+"\r\n\r\n";
            Application.DoEvents();
        }

        private string GetFileNameFromPath(string strFile)
        {
            int index = strFile.LastIndexOf("\\");
            if (index == -1)
            {
                return strFile;
            }
            return strFile.Substring(index + 1);
        }

        private void Publish2Branch(string strPublishPath,string strBranchPath,string strPublishFile)
        {
            if (strPublishFile == "")
            {
                return;
            }           

            CreatePath(strPublishPath, strBranchPath, strPublishFile);

            string relativePath = strPublishFile.Replace(strPublishPath,"");
            if (relativePath.StartsWith("\\"))
            {
                relativePath = relativePath.Substring(1);
            }
            string strBranchFilePath = strBranchPath + "\\" + relativePath;

            RecordMessage("Copy file from :" + strPublishFile+"\r\n-->:"+GetFileNameFromPath(strBranchFilePath));

            try
            {
                File.Copy(strPublishFile, strBranchFilePath);
            }
            catch (Exception ex)
            {
                RecordMessage("Error:"+ex.Message);
            }

        }

        private void CreatePath(string strPublishPath, string strBranchPath, string strPublishFile)
        {
            string relativePath = strPublishFile.Replace(strPublishPath,"");
            if (relativePath.StartsWith("\\"))
            {
                relativePath = relativePath.Substring(1);
            }

            int index = relativePath.IndexOf("\\");
            string temp = "";

            while (index>-1)
            {
                temp = temp+"\\"+relativePath.Substring(0, index);
                if (temp.EndsWith("\\"))
                {
                    temp = temp.Substring(0, temp.Length - 1);
                }

                if (!Directory.Exists(strBranchPath + "\\" + temp))
                {
                    Directory.CreateDirectory(strBranchPath + "\\" + temp);
                }
                relativePath = relativePath.Substring(relativePath.IndexOf("\\")+1);
                index = relativePath.IndexOf("\\");
            }



        }

        private void AssortFile(string strFileList)
        {
            _fileList.Clear();
            Regex reg = new Regex(@"(\\|\/)?.*\..*");
            Match match = reg.Match(strFileList);
            while (match.Success)
            {
                FileList file = new FileList();
                string strFileName = match.Value;
                string strFilePath = "";
                //MessageBox.Show(match.Value);
                strFileName = strFileName.Replace("\r","");

                if (strFileName.StartsWith("\\"))
                {
                    strFileName = strFileName.Substring(1);
                }

                if (strFileName.LastIndexOf("\\")>-1)
                {
                    strFilePath = strFileName.Substring(0,strFileName.LastIndexOf("\\") );
                    strFileName = strFileName.Substring(strFileName.LastIndexOf("\\") + 1);                    
                }

                bool isDll = false;
                file.FileName = ReplaceFileName(strFileName, ref isDll);
                file.IsDLL = isDll;
                file.FilePath = strFilePath;
                file.FileProjectType = GetProjectType(FindFile(strFileName, this.txtCodePath.Text.Trim(), "PrecompiledWeb"));

                this._fileList.Add(file);

                match = match.NextMatch();
            }
        }

        private string ReplaceFileName(string strFileName,ref bool isdll)
        {
            if (!strFileName.ToLower().EndsWith(".cs"))
            {
                return strFileName;
            }

            if (strFileName.ToLower().EndsWith(".aspx.cs"))
            {
                isdll = true;
                strFileName = strFileName.Replace(".aspx.cs", ".aspx");
            }
            else if (strFileName.ToLower().EndsWith(".ascx.cs"))
            {
                isdll = true;
                strFileName = strFileName.Replace(".ascx.cs", ".ascx");
            }
            else if (strFileName.ToLower().EndsWith(".master.cs"))
            {
                isdll = true;
                strFileName = strFileName.Replace(".master.cs", ".master");
            }

            return strFileName;
        }

        private ProjectType GetProjectType(string strFullPath)
        {
            ProjectType result = ProjectType.None;
            string relativePath = strFullPath.Replace(this.txtCodePath.Text.Trim(), "");
            if (relativePath.StartsWith("\\"))
            {
                relativePath = relativePath.Substring(1);
            }
            string strProjectName = relativePath;
            if (relativePath.IndexOf("\\") > -1)
            {
                strProjectName = relativePath.Substring(0, relativePath.IndexOf("\\"));
            }
            if (strProjectName == "BusinessRule")
            {
                result = ProjectType.BusinessRule;
            }
            else if (strProjectName == "Common")
            {
                result = ProjectType.Common;
            }
            else if (strProjectName == "CoreFramework")
            {
                result = ProjectType.CoreFramework;
            }
            else if (strProjectName == "DataAccess")
            {
                result = ProjectType.DataAccess;
            }
            else if (strProjectName == "EventMail")
            {
                result = ProjectType.EventMail;
            }
            else if (strProjectName == "FCKeditor.Net_2.5")
            {
                result = ProjectType.FCKeditor;
            }
            else if (strProjectName == "LogService")
            {
                result = ProjectType.LogService;
            }
            else if (strProjectName == "MailLink")
            {
                result = ProjectType.MailLink;
            }
            else if (strProjectName == "Modules")
            {
                result = ProjectType.Modules;
            }
            else if (strProjectName == "SpamAssassinChecker")
            {
                result = ProjectType.SpamAssassinChecker;
            }
            else if (strProjectName == "SystemAdmin")
            {
                result = ProjectType.SystemAdmin;
            }

            return result;
        }

        private string GetProjectDllName(ProjectType type)
        {
            switch (type)
            {
                case ProjectType.BusinessRule:
                    return "BusinessRule.dll";
                    break;
                case ProjectType.Common:
                    return "Common.dll";
                    break;
                case ProjectType.CoreFramework:
                    return "CoreFramework.dll";
                    break;
                case ProjectType.DataAccess:
                    return "DataAccess.dll";
                    break;
                case ProjectType.EventMail:
                    return "EventMail.dll";
                    break;
                case ProjectType.FCKeditor:
                    return "FredCK.FCKeditorV2.dll";
                    break;
                case ProjectType.LogService:
                    return "LogService.dll";
                    break;
                case ProjectType.MailLink:
                    return "MailLink.dll";
                    break;
                case ProjectType.Modules:
                    return "Modules.dll";
                    break;
                case ProjectType.SpamAssassinChecker:
                    return "SpamAssassinChecker.dll";
                    break;
                case ProjectType.SystemAdmin:
                    return "SystemAdmin.dll";
                    break;

            }
            return "";
        }

        private string FindDll(string strFileName)
        {
            return FindDllInFolder(this.txtPublishPath.Text.Trim(), strFileName);
        }

        private string FindFile(string strFileName)
        {
            return FindFileInFolder(this.txtPublishPath.Text.Trim(),strFileName);
        }

        private string FindFile(string strFileName,string strFolderPath,string strNotFindFolder)
        {
            return FindFileInFolder(strFolderPath, strFileName, strNotFindFolder);
        }

        private string FindDllInFolder(string strPath, string strFileName)
        {
            foreach (string strFilePath in Directory.GetFiles(strPath))
            {
                FileInfo info = new FileInfo(strFilePath);

                if (info.Name.ToLower().IndexOf(strFileName.ToLower()) > -1 && info.Name.EndsWith(".dll"))
                {
                    return strFilePath;
                }
            }

            foreach (string strFolderPath in Directory.GetDirectories(strPath))
            {
                string strResult = FindDllInFolder(strFolderPath, strFileName);

                if (strResult != "")
                {
                    return strResult;
                }
            }

            return "";
        }

        private string FindFileInFolder(string strPath, string strFileName)
        {
            return FindFileInFolder(strPath, strFileName,"");
        }

        private string FindFileInFolder(string strPath,string strFileName,string strNoFindFolder)
        {
            foreach (string strFilePath in Directory.GetFiles(strPath))
            {
                FileInfo info = new FileInfo(strFilePath);
                if (info.Name == strFileName)
                {
                    return strFilePath;
                }
            }

            foreach (string strFolderPath in Directory.GetDirectories(strPath))
            {
                string strFolderName=strFolderPath.Substring(strFolderPath.LastIndexOf("\\")+1);
                if (strNoFindFolder!="" && strNoFindFolder == strFolderName)
                {
                    continue;
                }
                string strResult = FindFileInFolder(strFolderPath, strFileName);

                if (strResult != "")
                {
                    return strResult;
                }
            }

            return "";
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnSelectPublisthPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "Select Publisth Path";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                if (dlg.SelectedPath != "")
                {
                    this.txtPublishPath.Text = dlg.SelectedPath;
                }
            }
            
        }

        private void btnSelectCodePath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "Select Code Path";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                if (dlg.SelectedPath != "")
                {
                    this.txtCodePath.Text = dlg.SelectedPath;
                }
            }
        }

        private void btnSelectBranchPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "Select Branch Path";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                if (dlg.SelectedPath != "")
                {
                    this.txtBranchPath.Text = dlg.SelectedPath;
                }
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            PathSetting set =  SettingHelp.Instance.GetSetting();
            if (set == null)
                return;


            this.txtBranchPath.Text = set.BranchPath;
            this.txtCodePath.Text = set.CodePath;
            this.txtFileList.Text = set.FileList.Replace("\n","\r\n");
            this.txtPublishPath.Text = set.PublishPath;
        }
    }
}
